﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HynuIOTA.Entity;
using HynuIOTA;

namespace PermissionFilterTest
{
    class Program
    {

        /// <summary>
        /// 是区域请求
        /// </summary>
        protected static bool IsAreaRequest { get; set; }

        /// <summary>
        /// 请求区域名
        /// </summary>
        protected static string AreaName { get; set; }

        /// <summary>
        ///  请求Action方法名
        /// </summary>
        protected static string ActionName { get; set; }

        /// <summary>
        /// 请求控制器名
        /// </summary>
        protected static string ControllerName { get; set; }

        /// <summary>
        /// 请求方法名
        /// </summary>
        protected static string Method { get; set; }

        static void Main(string[] args)
        {
            Test();
            Console.ReadLine();
        }

        private static void Test()
        {
            HynuIOTA.Entity.Action allArea = new HynuIOTA.Entity.Action() { rArea = "*" };
            HynuIOTA.Entity.Action allController = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "*" };
            HynuIOTA.Entity.Action allAction = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "User", rAction = "*" };

            HynuIOTA.Entity.Action registerGet = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "User", rAction = "Register", rMethod = "GET" };
            HynuIOTA.Entity.Action registerPost = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "User", rAction = "Register", rMethod = "POST" };

            HynuIOTA.Entity.Action delGet = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "Content", rAction = "Del", rMethod = "GET" };
            HynuIOTA.Entity.Action delPost = new HynuIOTA.Entity.Action() { rArea = "Admin", rController = "Content", rAction = "Del", rMethod = "POST" };

            HynuIOTA.Entity.Action noArea = new HynuIOTA.Entity.Action() { rController = "Home", rAction = "Index", rMethod = "GET" };

            List<HynuIOTA.Entity.Action> anymouse = new List<HynuIOTA.Entity.Action>() { registerGet, registerPost, noArea }; // 匿名用户 注册get post权限
            List<HynuIOTA.Entity.Action> user = new List<HynuIOTA.Entity.Action>() { registerGet, registerPost, delGet, delPost, noArea }; // 普通用户 注册 博客管理权限
            List<HynuIOTA.Entity.Action> admin = new List<HynuIOTA.Entity.Action>() { delGet, delPost, registerGet, registerPost, allAction, noArea }; // 管理员 删除博客 注册博客 User其它acion
            List<HynuIOTA.Entity.Action> superAdmin = new List<HynuIOTA.Entity.Action>() { allController, noArea }; // 超级管理员 所有controller
            List<HynuIOTA.Entity.Action> Administrator = new List<HynuIOTA.Entity.Action>() { allArea }; // 内置管理员 所有区域

            IsAreaRequest = true;
            AreaName = "Core";
            ControllerName = "";
            ActionName = "";
            Method = "";
            // 测试内置用户
            Console.WriteLine($"测试内置用户. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");

            // 测试超级管理员
            AreaName = "Admin";
            ControllerName = "Core";
            ActionName = "";
            Method = "";
            Console.WriteLine($"测试超级管理员. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");

            // 测试管理员
            AreaName = "Admin";
            ControllerName = "User";
            ActionName = "HaHa";
            Method = "";
            Console.WriteLine($"测试管理员. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");

            // 测试普通用户
            AreaName = "Admin";
            ControllerName = "Content";
            ActionName = "Del";
            Method = "POST";
            Console.WriteLine($"测试普通用户. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");

            // 测试匿名用户
            AreaName = "Admin";
            ControllerName = "User";
            ActionName = "Register";
            Method = "GET";
            Console.WriteLine($"测试匿名用户. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");

            // 测试无域
            IsAreaRequest = false;
            AreaName = "";
            ControllerName = "Home";
            ActionName = "Index";
            Method = "GET";
            Console.WriteLine($"测试无域. 匿名{HsPermission(anymouse)},   普通用户{HsPermission(user)},   管理员{HsPermission(admin)},   超级管理员{HsPermission(superAdmin)},  内置管理员{HsPermission(Administrator)}");
        }

        /// <summary>
        /// 判断是否有权限
        /// </summary>
        /// <returns></returns>
        private static bool HsPermission(ICollection<HynuIOTA.Entity.Action> actions)
        {
            // 构造 请求方法过滤  
            Func<HynuIOTA.Entity.Action, bool> method = (a) => a.rMethod == "*" || (a.rMethod == Method);
            // 构造 Action过滤
            Func<HynuIOTA.Entity.Action, bool> action = (a) => a.rAction == "*" || (a.rAction == ActionName && method(a));
            // 构造 控制器过滤
            Func<HynuIOTA.Entity.Action, bool> controller = (a) => a.rController == "*" || (a.rController == ControllerName && action(a));
            // 构造 有域请求情况下的过滤
            Func<HynuIOTA.Entity.Action, bool> haveArea = (a) => (a.rArea == "*") || (a.rArea == AreaName && controller(a));
            // 构造 无域请求下的过滤
            Func<HynuIOTA.Entity.Action, bool> noArea = (a) => a.rArea == "*" || controller(a);

            //Func<HynuIOTA.Entity.Action, bool> whereLambda = (a) =>
            //{
            //    return a.rController == "*" || (a.rController == ControllerName 
            //           && (a.rAction == "*" || (a.rAction == ActionName 
            //           && (a.rMethod == "*" || (a.rMethod == Method)))));
            //};

            //// 构造 有域请求情况下的过滤
            //Func<HynuIOTA.Entity.Action, bool> haveArea = (a) => (a.rArea == "*") || (a.rArea == AreaName && whereLambda(a));
            //// 构造 无域请求下的过滤
            //Func<HynuIOTA.Entity.Action, bool> noArea = (a) => a.rArea == "*" || whereLambda(a);

            // 根据请求类型，选择控制器过滤方式
            IEnumerable<HynuIOTA.Entity.Action> result = null;
            if (IsAreaRequest)
            {
                result = actions.Where(haveArea);
            }
            else
            {
                result = actions.Where(noArea);
            }

            // 如果返回结果中有元素，那么代表有权限
            if (result.Any())
            {
                return true;
            }

            return false;
        }
    }
}
